import abiturklassen.netzklassen.*;
import java.util.*;

//TODO noch fuer mich
//- die Klassen von Marcel mit dem Server verbinden
//      riesengroße aufgabe, die viel Zeit in Anspruch nimmt, aber bereits begonnen habt
//- moeglichkeit herstellen, dass Benutzer gespeichert und geladen werden koennen
//      mithilfe einer Textdatei realisierbar, in der die Benutzername+Passwort gespeichert werden
//      und dann bei einem Serverneustart sofort neu initialisiert werden
//- evtl dass man automatisch in eine Lobby kommt, wenn man diese manuell erstellt
//      das muss noch getestet werde (sowohl bei automatisch, als auch bei manuell)

/**
 * Dies ist die Klasse des Servers, der die Spielleitung uebernehmen wird.
 * Geschrieben wurde sie von Tobi ab dem 08.01.15 fuer das Projektspiel CAH.
 */
public class CAHServer extends abiturklassen.netzklassen.Server {
    private ArrayList<Nutzer> meineNutzer;
    private ArrayList<Lobby> meineLobbies;

    /**
     * Konstruktor der Klasse CAHServer. Man benötigt als Parameter nur die IP unter der der Server laufen soll.
     */public CAHServer(int pIP) {
        super(pIP);
        meineNutzer = new ArrayList<Nutzer>();
        meineLobbies = new ArrayList<Lobby>();
        ladeNutzer();
        System.out.println("-------------------------\n"+"DIES IST DAS AUSGABEFENSTER DES SERVERS");
    }

    //STANDARDMETHODEN EINES SERVERS DER ZABIKLASSEN

    /**
     * Falls eine neue Connection besteht, wird diese aufgefordert sich anzumelden. Man meldet sich direkt mit
     * dem Benutzernamen und dem Passwort an. Dies wird aber fortgesetzt in der Methode processMessage().
     */
    public void processNewConnection(String pClientIP, int pClientPort) {
        sendeNachricht(pClientIP, pClientPort, "Server: Geben Sie ihren Benutzernamen ein oder erstellen Sie einen neuen Nutzer! (Bitte ohne Sonderzeichen)");
    }

    /**
     * Diese Methode behandelt alle Nachrichten, die einkommen.
     * Sie ist dadurch aufgebaut, dass geprüft wird welcher Befehl ausgeführt wird. Dieser Befehl
     * wird dann in der jeweiligen Methode weiterverarbeitet.
     */
    public void processMessage(String pClientIP, int pClientPort, String pMessage) {
        System.out.println("Ich habe folgende Nachricht erhalten: " + pMessage);

        //Eingabemoeglichkeiten fuer alle
        if (pMessage.startsWith("BN:")) {
            anmeldung(pClientIP, pClientPort, pMessage);
        }
        else if (pMessage.startsWith("NBN:")) {
            neueAnmeldung(pClientIP, pClientPort, pMessage);
        }
        else if (pMessage.startsWith("END")) {
            beendeVerbindung(pClientIP, pClientPort);
        }
        else if (pMessage.startsWith("N:")) {
            neueNachrichtEmpfangen(pClientIP, pClientPort, pMessage);
        }
        else if (pMessage.startsWith("FA:")) {
            faGesendet(pClientIP, pClientPort, pMessage.substring(3));
        }
        else if (pMessage.startsWith("FB:")) {
            faBestaetigt(pClientIP, pClientPort, pMessage.substring(3));
        }
        else if (pMessage.startsWith("FL:")) {
            freundschaftLoeschen(pClientIP, pClientPort, pMessage.substring(3));
        }
        else if (pMessage.startsWith("VL")) {
            lobbyVerlassen(pClientIP, pClientPort);
        }
        //Administratoreingaben
        else if (pMessage.startsWith("/ReloadNutzer")) {
            reloadNutzer(pClientIP, pClientPort);
        }
        else if (pMessage.startsWith("/NL:")) {
            int anzahlSpieler = Integer.parseInt(pMessage.substring(4));
            automatischNeueLobbyErstellen(pClientIP, pClientPort, anzahlSpieler);
        }
        else if (pMessage.startsWith("/MNL:")) {
            manuelleNeueLobbyErstellen(pClientIP, pClientPort, pMessage.substring(5));
        }
        else if (pMessage.startsWith("/ENDSERVER")) {
            beendeServer();
        }

        //moegliche Nachrichten, die fuer den Spielverlauf wichtig sind
        else if (pMessage.startsWith("/NG:")) {
            beginneNeuesSpiel(pClientIP, pClientPort, pMessage.substring(4));
        }
        else if (pMessage.startsWith("/1K:")) {
            eineKarteAusgewaehlt(pClientIP, pClientPort, pMessage.substring(4));
        }
        else if (pMessage.startsWith("/2KN:")) {
            zweiKartenAusgewaehlt(pClientIP, pClientPort, pMessage.substring(5));
        }
        else if (pMessage.startsWith("/KW:")) {
            antwortGeben(pClientIP, pClientPort, pMessage.substring(4));
        }
    }

    /**
     * Diese Methode funktioniert noch nicht!!
     */
    public void beendeServer() {
        speicherNutzer();
        sendeNachrichtZuAllen("Server: Der Server wird in 5 Sekunden geschlossen");
        //hier 5 sekunden zeitverzögerung einbauen
        //try (Thread.sleep(5000)) {
        //
        //} catch {}
        close();
    }

    private void speicherNutzer() {
        //das muss ich mir angucken wie das geht
    }

    private void ladeNutzer() {
        //das muss ich mir auch angucken wie das geht
    }

    //METHODEN DIE WICHTIG SIND FUER DEN SPIELVERLAUF

    public void beginneNeuesSpiel(String pClientIP, int pClientPort, String pMessage) {
        Nutzer erstellNutzer = searchNutzer(pClientIP, pClientPort);
        if (erstellNutzer.getIstAdmin()==false) {
            sendeNachricht(pClientIP, pClientPort, "Server: Sie haben keine Berechtigung ein neues Spiel zu erstellen, da sie nicht der Admin der Lobby sind");
            return;
        }
        //ueberpruefen in welcher Lobby sich dieser Spieler momentan befindet
        Lobby lobby = new Lobby(0);
        boolean lobbyGefunden = false;
        for (int i=0; i<meineLobbies.size(); i++) {
            if (meineLobbies.get(i).istNutzerEnthalten(erstellNutzer)) {
                lobby = meineLobbies.get(i);
                lobbyGefunden = true;
            }
        }
        if (lobbyGefunden == false) {
            sendeNachricht(pClientIP, pClientPort, "Server: Sie sind in keiner Lobby!");
            return;
        }
        //neues Spiel beginnen
        if (lobby.getSpielLaeuft() == false) { //ueberprueft ob das SPiel evtl schon laueft
            lobby.setSpielLaeuftTrue();
            lobby.starteSpiel(Integer.parseInt(pMessage), lobby.getNutzer());
            sendeNachricht(pClientIP, pClientPort, "Server: Sie als Admin haben das Spiel gestartet!");
            sendeNachrichtAnArrayList(lobby.getNutzer(), "Server: Das Spiel wurde gestartet.");
            sendeNachrichtAnArrayList(lobby.getNutzer(), "/nP:"+lobby.getSpiel().getAnzSiege());
            for (int i=0; i<lobby.getSpiel().getSpieler().size(); i++) {
                sendeNachrichtAnArrayList(lobby.getNutzer(), "/nS:"+lobby.getSpiel().getSpieler().get(i).name);
            }
            //wir suchen die Jury
            for (int i=0; i<lobby.getSpiel().getSpieler().size(); i++) {
                if (lobby.getSpiel().getSpieler().get(i).getJury() == true) {
                    Nutzer jury = searchNutzer(lobby.getSpiel().getSpieler().get(i).getNutzer().getBenutzername());
                    sendeNachricht(jury.getIP(), jury.getPort(), "/iJ:Game: Sie sind in dieser Runde die Jury und dürfen keine Karte wählen. Suchen Sie nach der Auforderung ihre gewünschte Karte aus!");
                }
            }
            sendeFrage(lobby);
            sendeKarten(lobby);
            // sendeNachrichtAnArrayList(lobby.getNutzer(), "Game: Bitte waehlen Sie ihre Karte aus");
            for (int i=0; i<lobby.getNutzer().size(); i++) {
                lobby.getNutzer().get(i).anzahlSpieleErhoehen();
            }
        } else sendeNachricht(pClientIP, pClientPort, "Server: Das Spiel laeuft bereits!");
    }

    public void sendeKarten(Lobby l) {
        for (int i=0; i<l.getSpiel().getSpieler().size(); i++) { //jeder Nutzer wird durchgegangen
            Player p = l.getSpiel().getSpieler().get(i);
            // sendeNachricht(p.getNutzer().getIP(), p.getNutzer().getPort(), "Game: Ihre Karten sind folgende:");
            sendeNachricht(p.getNutzer().getIP(), p.getNutzer().getPort(), "/k1:Karte 1: "+p.getCard1());
            sendeNachricht(p.getNutzer().getIP(), p.getNutzer().getPort(), "/k2:Karte 2: "+p.getCard2());
            sendeNachricht(p.getNutzer().getIP(), p.getNutzer().getPort(), "/k3:Karte 3: "+p.getCard3());
            sendeNachricht(p.getNutzer().getIP(), p.getNutzer().getPort(), "/k4:Karte 4: "+p.getCard4());
            sendeNachricht(p.getNutzer().getIP(), p.getNutzer().getPort(), "/k5:Karte 5: "+p.getCard5());
            sendeNachricht(p.getNutzer().getIP(), p.getNutzer().getPort(), "/k6:Karte 6: "+p.getCard6());
        }
    }

    public void sendeFrage(Lobby l) {
        //         sendeNachrichtAnArrayList(l.getNutzer(), "Game: Die Frage fuer diese Runde lautet:");
        sendeNachrichtAnArrayList(l.getNutzer(), "/F"+l.getSpiel().getAnzAnt()+":"+l.getSpiel().frage);
    }

    public void eineKarteAusgewaehlt(String pClientIP, int pClientPort, String pMessage) {
        int kn = Integer.parseInt(pMessage);
        Nutzer n = searchNutzer(pClientIP, pClientPort);
        Lobby l = sucheMirLobby(n);
        l.getSpiel().getPlayer(n.getBenutzername()).eineAntwortGeben(kn);
        //pruefe ob mittelrweile alle antworten gegeben wurden
        l.getSpiel().alleAnt();
        if (l.getSpiel().alleAnt) {
            //alle haben gegeben
            ArrayList<String> antworten = l.getAntwortenAll();
            for (int i=0; i<antworten.size(); i++) {
                sendeNachrichtAnArrayList(l.getNutzer(), "/an:"+antworten.get(i));
            }
        }
    }

    public void zweiKartenAusgewaehlt(String pClientIP, int pClientPort, String pMessage) {
        int kn1 = Integer.parseInt(pMessage.substring(0,1));
        int kn2 = Integer.parseInt(pMessage.substring(1,2));
        Nutzer n = searchNutzer(pClientIP, pClientPort);
        Lobby l = sucheMirLobby(n);
        l.getSpiel().getPlayer(n.getBenutzername()).zweiAntwortenGeben(kn1, kn2);
        //pruefe ob mittelrweile alle antworten gegeben wurden
        l.getSpiel().alleAnt();
        if (l.getSpiel().alleAnt) {
            //alle haben gegeben
            ArrayList<String> antworten = l.getAntwortenAll();
            
            for (int i=0; i<antworten.size(); i++) {

                sendeNachrichtAnArrayList(l.getNutzer(), "/an:" +antworten.get(i));
            }
        }
    }

    public Lobby sucheMirLobby(Nutzer n) {
        for (int i=0; i<meineLobbies.size(); i++) {
            if (meineLobbies.get(i).istNutzerEnthalten(n)) {
                return meineLobbies.get(i);
            }
        }
        return null;
    }

    public void antwortGeben(String pClientIP, int pClientPort, String pMessage) {
        Nutzer n = searchNutzer(pClientIP, pClientPort);
        Lobby l = sucheMirLobby(n);
        Player pl = l.getSpiel().getPlayer(n.getBenutzername());
        if (l.getNutzerFromAntwort(pMessage) == null) {
            sendeNachricht(pClientIP, pClientPort, "Game: Dieser Nutzer ist nicht vorhanden!");
        }
        if (pl.getJury() == true) {
            l.getSpiel().alleAnt();
            if (l.getSpiel().alleAnt == true) {
                int nummer = l.getSpiel().stelleVonNutzer(l.getNutzerFromAntwort(pMessage).getBenutzername());
                if (nummer > -1) {
                    pl.setWahl(nummer);
                    l.getSpiel().spielVerlauf();
                    //hier weiterarbeiten indem wir die einzelnen Gewinner der Runde und Gesamtgewinner suchen undso
                    sendeNachrichtAnArrayList(l.getNutzer(), "Game: Diese Runde hat "+l.getSpiel().getGewinnerRunde()+" gewonnen!");
                    sendeNachrichtAnArrayList(l.getNutzer(), "/Si:"+l.getSpiel().getGewinnerRunde());
                    if (l.getSpiel().istSpielEnde() == true) {
                        sendeNachrichtAnArrayList(l.getNutzer(), "Game: Das gesamte Spiel hat "+l.getSpiel().getNameGewinnerEnde()+" gewonnen!");
                        l.setSpielLaueftFalse();
                        //suche die Person die gewonnen hat aus
                        for (int i=0; i<l.getNutzer().size(); i++) {
                            if (l.getNutzer().get(i).getBenutzername().equals(l.getSpiel().getNameGewinnerEnde())) {
                                l.getNutzer().get(i).anzahlSiegeErhoehen();
                            }
                        }
                    } else {
                        neueRunde(l);
                    }
                    //hier kann man noch eine Platzierung des gesamten Spiels erstellen wenn noch Zeit bleibt
                } else sendeNachricht(pClientIP, pClientPort, "Game: Dieser Nutzer ist nicht vorhanden!");
            } else sendeNachricht(pClientIP, pClientPort, "Game: Es wurden noch nicht alle Antworten ausgegeben!");
        } else sendeNachricht(pClientIP, pClientPort, "Game: Sie sind in dieser Runde nicht Jury und dürfen somit nicht abstimmen, bitch!");
    }

    private void neueRunde(Lobby lobby) {
        sendeNachrichtAnArrayList(lobby.getNutzer(), "/nR:Game: Die nächste Runde beginnt!");
        //wir suchen die Jury
        for (int i=0; i<lobby.getSpiel().getSpieler().size(); i++) {
            if (lobby.getSpiel().getSpieler().get(i).getJury() == true) {
                Nutzer jury = searchNutzer(lobby.getSpiel().getSpieler().get(i).getNutzer().getBenutzername());
                sendeNachricht(jury.getIP(), jury.getPort(), "/iJ:Game: Sie sind in dieser Runde die Jury und dürfen keine Karte wählen");
            }
        }
        sendeFrage(lobby);
        sendeKarten(lobby);
        sendeNachrichtAnArrayList(lobby.getNutzer(), "Game: Bitte waehlen Sie ihre Karte aus");
    }

    //METHODEN FUER DAS VERSENDEN VON NACHRICHTEN

    /**
     * Diese Methode sendet eine Nachricht an einen ganz bestimmten Nutzer. Man benötigt hierfür
     * sowohl den Port als auch die IP-Adresse.
     */
    private void sendeNachricht(String pClientIP, int pClientPort, String pMessage) {
        send(pClientIP, pClientPort, pMessage);
    }

    /**
     * Diese Methode sendet eine Nachricht an alle bestehenden Verbindungen (also nicht die offline Nutzer) aus.
     * Vor Allem wird dies gebraucht, wenn sich ein neuer Nutzer anmeldet.
     */
    private void sendeNachrichtZuAllen(String pMessage) {
        //normalerweise muesste man hierfuer diese Methode verwenden: sendToAll(pMessage); geht hier aber nicht, da sonst auch
        //unangemeldete Nutzer die Nachricht erhalten wuerden.
        for (int i=0; i<meineNutzer.size(); i++) {
            if (meineNutzer.get(i).getStatus() == 1) {
                send(meineNutzer.get(i).getIP(), meineNutzer.get(i).getPort(), pMessage);
            }
        }
    }

    /**
     * ausser zu einem selbst
     */
    private void sendeNachrichtZuAllenAusser(String pClientIP, int pClientPort, String pMessage) {
        for (int i=0; i<meineNutzer.size(); i++) {
            if (searchNutzer(pClientIP, pClientPort).equals(meineNutzer.get(i)) == false) {
                sendeNachricht(meineNutzer.get(i).getIP(), meineNutzer.get(i).getPort(), pMessage);
            }
        }
    }

    private void sendeNachrichtAnArrayList(ArrayList<Nutzer> pALN, String pMessage) {
        for (int i=0; i<pALN.size(); i++) {
            sendeNachricht(pALN.get(i).getIP(), pALN.get(i).getPort(), pMessage);
        }
    }

    /**
     * Falls in dem Chat eine Nachricht geschrieben wird, landet sie hier.
     * Wurde diese Nachricht an eine bestimmte Person gerichtet (@benutzername:), so geht sie an alle Nutzer.
     */
    private void neueNachrichtEmpfangen(String pClientIP, int pClientPort, String pMessage) {
        String tempMessage = pMessage.substring(2);
        Nutzer tempSender = searchNutzer(pClientIP, pClientPort);
        if (tempMessage.startsWith("@")) {
            tempMessage = tempMessage.substring(1);
            String tempBenutzer = tempMessage.split(":")[0];
            Nutzer tempEmpfaenger = searchNutzer(tempBenutzer);
            tempMessage = tempMessage.split(":")[1];
            if (tempEmpfaenger != null) {
                sendeNachricht(tempEmpfaenger.getIP(), tempEmpfaenger.getPort(), tempSender.getBenutzername()+" fluestert: "+tempMessage);
                sendeNachricht(pClientIP, pClientPort, "Ich fluester an "+tempEmpfaenger.getBenutzername()+": "+tempMessage);
            } else {
                sendeNachricht(pClientIP, pClientPort, "Server: Dieser Benutzer wurde nicht gefunden. Die Nachricht wird nicht versendet");
            }
        } else {
            sendeNachrichtZuAllenAusser(pClientIP, pClientPort, tempSender.getBenutzername()+": "+tempMessage);
            sendeNachricht(pClientIP, pClientPort, "Ich: "+tempMessage);
        }
    }

    //METHODEN FUER DIE FREUNDSCHAFTEN (BESTAETIGUNGEN, ANFRAGEN,...)

    private void faGesendet(String pClientIP, int pClientPort, String pMessage) {
        if (searchNutzer(pMessage) != null) {
            if (searchNutzer(pMessage).istInAnfragenEnthalten(searchNutzer(pClientIP, pClientPort).getBenutzername()) == true) {
                sendeNachricht(pClientIP, pClientPort, "Server: Diesem Nutzer steht noch eine ihrer Freundschaftsanfragen aus.");
                return;
            }
            searchNutzer(pMessage).faErhalten(searchNutzer(pClientIP, pClientPort));
            sendeNachricht(searchNutzer(pMessage).getIP(), searchNutzer(pMessage).getPort(),
                "Server: "+searchNutzer(pClientIP, pClientPort).getBenutzername()+" hat ihnen eine Freundschaftsanfrage gesendet. Moechten Sie diese annehmen?");
        } else sendeNachricht(pClientIP, pClientPort, "Server: Der Nutzer ist leider nicht vorhanden!");
    }

    private void faBestaetigt(String pClientIP, int pClientPort, String pMessage) {
        if (searchNutzer(pClientIP, pClientPort).istInAnfragenEnthalten(pMessage)) {
            searchNutzer(pClientIP, pClientPort).faAngenommen(searchNutzer(pMessage));
            sendeNachricht(searchNutzer(pMessage).getIP(), searchNutzer(pMessage).getPort(),
                "Server: "+searchNutzer(pClientIP, pClientPort).getBenutzername()+" hat ihre Freundschaftsanfrage bestaetigt");
            searchNutzer(pMessage).faBestaetigt(searchNutzer(pClientIP, pClientPort));
        } else sendeNachricht(pClientIP, pClientPort, "Server: Von diesem Nutzer haben Sie keine Freundschaftsanfrage erhalten.");
    }

    private void freundschaftLoeschen(String pClientIP, int pClientPort, String pMessage) {
        if (searchNutzer(pMessage) == null) {
            sendeNachricht(pClientIP, pClientPort, "Server: Der Nutzer "+pMessage+" existiert nicht!");
        } else if (searchNutzer(pClientIP, pClientPort).istInFreundenEnthalten(pMessage) == false) {
            sendeNachricht(pClientIP, pClientPort, "Server: Der Nutzer "+pMessage+" ist nicht ihr Freund.");
        } else {
            searchNutzer(pMessage).deleteFreund(searchNutzer(pClientIP, pClientPort));
            sendeNachricht(pClientIP, pClientPort, "Sie sind nun nicht mehr der Freund von "+searchNutzer(pMessage)+".");
            searchNutzer(pClientIP, pClientPort).deleteFreund(searchNutzer(pMessage));
            sendeNachricht(searchNutzer(pMessage).getIP(), searchNutzer(pMessage).getPort(), "Der Nutzer "+searchNutzer(pClientIP, pClientPort)+" will nicht mehr ihr Freund sein.");
        }
    }

    //SUCHMETHODEN

    /**
     * Die folgende Methode ist eine Hilfsmethode. Durch die IP und den Port eines Nutzers kann der gesamte Nutzer
     * zurückgegeben werden. Diese Methode wird häufig in anderen Methoden aufgerufen und verwendet.
     */
    private Nutzer searchNutzer(String pClientIP, int pClientPort) {
        for (int i=0; i<meineNutzer.size(); i++) {
            if (meineNutzer.get(i).getPort() == pClientPort && meineNutzer.get(i).getIP().equals(pClientIP)) {
                return meineNutzer.get(i);
            }
        }
        return null;
    }

    /**
     * Die folgende Methode ist ebenso eine Hilfsmethode. Durch den Benutzernamen eines Nutzers wird der
     * gesamte Nutzer zurückgegeben. Auch diese Methode wird viel in anderen Methoden verwendet.
     */
    private Nutzer searchNutzer(String benutzername) {
        for (int i=0; i<meineNutzer.size(); i++) {
            if (meineNutzer.get(i).getBenutzername().equals(benutzername)) {
                return meineNutzer.get(i);
            }
        }
        return null;
    }

    //METHODEN FUER DIE ARBEIT MIT EINER LOBBY

    /**
     * Dies ist die Methode, die die Nutzer in die einzelnen Lobbies verteilt.
     * Es wird nach dem Prinzip gearbeitet, dass der Nutzer, der am laengsten bereits eingeloggt ist
     */
    private void automatischNeueLobbyErstellen(String pClientIP, int pClientPort, int pAnzahlSpieler) {
        //falls mehr Spieler gefordert werden, obwohl weniger angemeldet sind
        if (pAnzahlSpieler > aktuellOnlineNutzer().size()) {
            sendeNachricht(pClientIP, pClientPort, "Server: So viele Nutzer sind grade nicht verfügbar!");
            return;
        }
        Lobby tempLobby = new Lobby(pAnzahlSpieler);
        ArrayList<Nutzer> aktuellOnlineNutzer = aktuellOnlineNutzer(); //online bedeutet, dass sie zudem auch noch nicht in einem Spiel sind
        boolean istErstellerDrin = false;
        while (tempLobby.getEingefuegteNutzer() < tempLobby.getGroesse()) {
            //zuerst wird der Nutzer eingefuegt, der die Methode ausgefuehrt hat
            Nutzer tempNutzer;
            if (istErstellerDrin == false) {
                tempNutzer = searchNutzer(pClientIP, pClientPort);
                istErstellerDrin = true;
                tempNutzer.setAdminDerLobby();
            } else {
                tempNutzer = getErstenNutzerEinerArrayList(aktuellOnlineNutzer);
            }
            if (tempNutzer != null) {
                if (istInListe(tempLobby.getNutzer(), tempNutzer) == false) {
                    tempLobby.nutzerEinfuegen(tempNutzer);
                    tempNutzer.setStatus(2);
                    aktuellOnlineNutzer.remove(tempNutzer);
                }
                //die freunde die noch online sind und keine Lobby haben werden hinzugefuegt
                if (tempNutzer.getOnlineFreunde().size() > 0) {
                    for (int i=0; i<tempNutzer.getOnlineFreunde().size(); i++) {
                        if (tempLobby.getNutzer().size() == pAnzahlSpieler) return;
                        if (istInListe(tempLobby.getNutzer(), tempNutzer.getOnlineFreunde().get(i)) == false) {
                            tempLobby.nutzerEinfuegen(tempNutzer.getOnlineFreunde().get(i));
                            tempNutzer.getOnlineFreunde().get(i).setStatus(2);
                        }
                    }
                }
            }
        }
        if (tempLobby.getEingefuegteNutzer() < pAnzahlSpieler) {
            sendeNachrichtAnArrayList(tempLobby.getNutzer(), "Server: Die Lobby wurde nur aus "
                +tempLobby.getEingefuegteNutzer()+" erstellt, anstatt mit "+pAnzahlSpieler+".");
        } else  {
            sendeNachrichtAnArrayList(tempLobby.getNutzer(),
                "Server: Die Lobby wurde mit der gewuenschten Anzahl an Spielern ("+pAnzahlSpieler+") erstellt.");
        }
        meineLobbies.add(tempLobby);
    }

    private void manuelleNeueLobbyErstellen(String pClientIP, int pClientPort, String pMessage) {
        Lobby tempLobby = new Lobby(0);
        String tempMessage = pMessage;
        boolean istErstellerDrin = false;
        while (!tempMessage.isEmpty()) {
            if (!tempMessage.startsWith("END")) {
                String tempNutzer;
                //zuerst wird der nutzer eingetragen, der auch das Spiel erstellt hat
                if (istErstellerDrin == false) {
                    tempNutzer = searchNutzer(pClientIP, pClientPort).getBenutzername();
                    istErstellerDrin = true;
                    searchNutzer(pClientIP, pClientPort).setAdminDerLobby();
                } else {
                    tempNutzer = tempMessage.substring(0,tempMessage.indexOf(";"));
                    tempMessage = tempMessage.substring(tempMessage.indexOf(";")+1);
                }
                if (searchNutzer(tempNutzer) != null) {
                    if (searchNutzer(tempNutzer).getStatus() == 1) {
                        searchNutzer(tempNutzer).setStatus(2);
                        tempLobby.nutzerManuellEinfuegen(searchNutzer(tempNutzer));
                    } else {
                        sendeNachricht(pClientIP, pClientPort, "Der Nutzer "+tempNutzer+" ist leider momentan in einem Spiel");
                    }
                } else sendeNachricht(pClientIP, pClientPort, "Es gibt keinen Nutzer mit dem Namen "+tempNutzer+"!");
            } else {
                meineLobbies.add(tempLobby);
                sendeNachrichtAnArrayList(tempLobby.getNutzer(), "Die Lobby wurde manuell aus "+tempLobby.getNutzer().size()+" Nutzern erstellt.");
                return;
            }
        }
    }

    public ArrayList<Lobby> getMeineLobbies() {
        return meineLobbies;
    }

    private void lobbyVerlassen(String pClientIP, int pClientPort) {
        Nutzer pNutzer = searchNutzer(pClientIP, pClientPort);
        for (int i=0; i<meineLobbies.size(); i++) {
            if (meineLobbies.get(i).nutzerEntfernen(pNutzer) == true) {
                //wenn der sich abmeldende Nutzer der Admin war, wird dieses Recht auf jemand anderes uebertragen
                if (pNutzer.getIstAdmin() == true) {
                    pNutzer.resetAdminDerLobby();
                    meineLobbies.get(i).neuenAdminZuordnen().setAdminDerLobby();
                }
                sendeNachricht(pClientIP, pClientPort, "Server: Sie haben die Lobby verlassen");
                searchNutzer(pClientIP, pClientPort).setStatus(1);
                //es kann hier ja sein dass die Lobby nun leer ist. Dann kann sie auch geloescht werden
                if (meineLobbies.get(i).getNutzer().size() == 0) {
                    meineLobbies.remove(meineLobbies.get(i));
                }
                return;
            }
        }
        sendeNachricht(pClientIP, pClientPort, "Server: Sie sind momentan in keiner Lobby vorhanden");
    }

    //ABFRAGEMETHODEN

    private boolean istInListe(ArrayList<Nutzer> liste, Nutzer nutzer) {
        for (int i=0; i<liste.size(); i++) {
            if (liste.get(i).equals(nutzer)) {
                return true;
            }
        }
        return false;
    }

    private Nutzer getErstenNutzerEinerArrayList(ArrayList<Nutzer> pALN) {
        for (int i=0; i<pALN.size(); i++) {
            if (pALN.get(i) != null) {
                return pALN.get(i);
            }
        }
        return null;
    }

    private ArrayList<Nutzer> aktuellOnlineNutzer() {
        //online bedeutet, dass sie sich noch nicht in einem Spiel befinden und eine Verbindung besteht
        ArrayList<Nutzer> aktuellOnlineNutzer = new ArrayList<Nutzer>();
        for (int i=0; i<meineNutzer.size(); i++) {
            if (meineNutzer.get(i).getStatus() == 1) {
                aktuellOnlineNutzer.add(meineNutzer.get(i));
            }
        }
        return aktuellOnlineNutzer;
    }

    /**
     * Falls vom Administrator eingegeben kann die Liste der momentan verbundenen Spieler zurückgegeben werden.
     * Hierzu wird nochmal unterschieden zwischen einem Nutzer, der online ist und einem Nutzer, der sich bereits
     * in einem Spiel befindet.
     */
    private void reloadNutzer(String pClientIP, int pClientPort) {
        //alle Nutzer die online sind werden ausgegeben
        String tempNutzerOnline = "Server: Momentan sind folgende Nutzer online: ";
        String tempNutzerImSpiel = "\nMomentan sind folgende Nutzer im Spiel: ";
        for (int i=0; i<meineNutzer.size(); i++) {
            if (meineNutzer.get(i).getStatus() == 1) {
                tempNutzerOnline = tempNutzerOnline + meineNutzer.get(i).getBenutzername() + ", ";
            } else if (meineNutzer.get(i).getStatus() == 2) {
                tempNutzerImSpiel = tempNutzerImSpiel + meineNutzer.get(i).getBenutzername() + ", ";
            }
        }
        send(pClientIP, pClientPort, tempNutzerOnline+tempNutzerImSpiel);
    }

    //METHODEN FUER DIE ANMELDUNG UND ABMELDUNG

    /**
     * Diese Methode ist privat, da sie unter den richtigen Bedingungen in der Methode processMessage aufgerufen wird.
     * In dieser Methode kann sich ein Spieler, der bereits in der Nutzerliste ist, anmelden.
     * Hierzu wird der Benutzername auf Verfügbarkeit und das Passwort geprüft.
     */
    private void anmeldung(String pClientIP, int pClientPort, String pMessage) {
        String tempBenutzername = pMessage.split("/")[0].substring(3);
        String tempPasswort = pMessage.split("/")[1].substring(3);
        Nutzer tempNutzer = searchNutzer(tempBenutzername);
        if (tempNutzer != null) {
            if (tempNutzer.getStatus() >= 1) {
                sendeNachricht(pClientIP, pClientPort, "Server: Dieser Nutzer ist bereits angemeldet!");
                return;
            } else {
                if(tempPasswort.equals(tempNutzer.getPasswort())) {
                    tempNutzer.setStatus(1);
                    tempNutzer.setPort(pClientPort);
                    tempNutzer.setIP(pClientIP);
                    sendeNachricht(pClientIP, pClientPort, "Server: Sie wurden angemeldet. Dies wird allen Usern nun mitgeteilt");
                    sendeNachrichtZuAllen("Server: Der Nutzer "+tempBenutzername+ " ist nun eingeloggt");
                } else sendeNachricht(pClientIP, pClientPort, "Server: Das Passwort ist falsch! Melde dich neu an");
            }
        } else sendeNachricht(pClientIP, pClientPort, "Server: Der Benutzername ist nicht vorhanden!");
    }

    /**
     * Ein Spieler, der bis jetzt noch nicht angemeldet ist, kann sich durch diese Methode anmelden.
     * Falls der Benutzername noch vorhanden ist und die zwei Passwörtereingaben übereinstimmen, wird der
     * Nutzer der Liste hinzugefügt.
     */
    private void neueAnmeldung(String pClientIP, int pClientPort, String pMessage) {
        String tempBenutzername = pMessage.split("/")[0].substring(4);
        String tempPasswort = pMessage.split("/")[1].substring(4);
        if (searchNutzer(tempBenutzername) != null) {
            sendeNachricht(pClientIP, pClientPort, "Server: Dieser Benutzername ist bereits vergeben!");
            return;
        }
        if (tempPasswort.split(";")[0].equals(tempPasswort.split(";")[1])) {
            meineNutzer.add(new Nutzer(tempBenutzername, tempPasswort.split(";")[0], pClientIP, pClientPort));
        } else {
            sendeNachricht(pClientIP, pClientPort, "Server: Die Passwoerter stimmen nicht ueberein!");
            return;
        }
        sendeNachricht(pClientIP, pClientPort, "Server: Der gewuenschte Nutzer wurde erstellt!");
        sendeNachrichtZuAllen("Server: Der Nutzer "+tempBenutzername+" ist nun auch angemeldet.");
    }

    /**
     * Durch diese Methode kann die Verbindung vom Server und dem jeweiligen Nutzer beendet werden, wobei
     * lediglich der Status veränbdert wird und der Nutzer selbst bleibt noch erhalten.
     */
    private void beendeVerbindung(String pClientIP, int pClientPort) {
        Nutzer tempNutzer = searchNutzer(pClientIP, pClientPort);
        if (tempNutzer != null) {
            if (tempNutzer.getStatus() == 0) {
                sendeNachricht(pClientIP, pClientPort, "Server: Dieser Nutzer ist nicht angemeldet");
                return;
            }
            searchNutzer(pClientIP, pClientPort).setStatus(0);
            sendeNachricht(pClientIP, pClientPort, "Server: Sie wurden abgemeldet");
        }
        sendeNachrichtZuAllen(tempNutzer.getBenutzername()+" hat sich ausgeloggt");
    }

    //TESTMETHODEN
    public String test(String nachricht) {
        return nachricht.substring(0,4) + " und " + nachricht.substring(4);
    }

    public String test2(String nachricht) {
        String temp = nachricht.substring(2);
        return temp;
    }

    public String test3(String nachricht) {
        String tempNutzer = nachricht.substring(nachricht.indexOf(";")+1);
        return tempNutzer;
    }

    public boolean startsWith(String nachricht, String s) {
        nachricht.startsWith(s);
        return true;
    }

    public String test4(String s) {
        return s.substring(0,1);
    }

    public int substring(String pMessage) {
        String dieFrage;
        int frageInt = Integer.parseInt(pMessage.substring(2,3));
        dieFrage = pMessage.substring(4, pMessage.length());
        return frageInt;
    }
}